import { Client, Room } from 'colyseus.js';
import { IUserInfo } from '../../global/user-hub-message-type';
import { MMO_ROOM_NAME, MMO_MESSAGE_TYPE, IPlayerJoinedMessage, IXYZMessage, IActionMessage, IBooleanMessage, IRoomStatePlayerMessage, IPlayerLeftMessage } from '../common';
import { Stage } from 'babylon-lib/base/stage';
import { CharacterManager } from './character-manager';
import { IPlayerInfo } from '../mmo-player';


class MultiplayerManager {

    private static _room: Room;
    private static _roomId: string;
    private static _serverUrl: string;
    private static _userInfo: IUserInfo;
    private static _stage: Stage;

    public static async initialize(roomId: string, serverUrl: string, playerInfo: IPlayerInfo, stage: Stage): Promise<void> {
        this._roomId = roomId;
        this._serverUrl = serverUrl;
        this._userInfo = playerInfo;
        this._stage = stage;
        await this.connectToServer();
        this.setMessageListener();
    }

    public static get room(): Room {
        return this._room;
    }

    private static async connectToServer(): Promise<void> {
        console.log('connect to server,roomId:', this._roomId);
        const client = new Client(this._serverUrl);
        this._room = await client.joinOrCreate<IPlayerJoinedMessage>(MMO_ROOM_NAME.GALLERY, {
            sessionId: this._roomId,
            player: this._userInfo
        })
    }

    private static setMessageListener() {
        const scope = MultiplayerManager;
        this._room.onMessage(MMO_MESSAGE_TYPE.ROOM_STATE_PLAYERS, (msg: IRoomStatePlayerMessage) => {
            for (const player of msg.players) {
                if (player[0] === scope._room.sessionId) continue;
                CharacterManager.addPlayer(player[0], player[1]);
            }
        });

        this._room.onMessage(MMO_MESSAGE_TYPE.PLAYER_JOINED, (msg: IPlayerJoinedMessage) => {
            if (msg.sessionId === scope._room.sessionId) return;
            CharacterManager.addPlayer(msg.sessionId, msg.player);
        });

        this._room.onMessage(MMO_MESSAGE_TYPE.PLAYER_LEFT, (msg: IPlayerLeftMessage) => {
            if (msg.sessionId === scope._room.sessionId) return;
            CharacterManager.removePlayer(msg.sessionId);
        });

        this._room.onMessage(MMO_MESSAGE_TYPE.PLAYER_POSITION, (msg: IXYZMessage) => {
            if (msg.sessionId === scope._room.sessionId) return;
            CharacterManager.setCharacterPosition(msg.sessionId, msg.x, msg.y, msg.z);
        });

        this._room.onMessage(MMO_MESSAGE_TYPE.PLAYER_ROTATION, (msg: IXYZMessage) => {
            if (msg.sessionId === scope._room.sessionId) return;
            CharacterManager.setCharacterRotation(msg.sessionId, msg.x, msg.y, msg.z);
        });

        this._room.onMessage(MMO_MESSAGE_TYPE.PLAYER_SCALE, (msg: IXYZMessage) => {
            if (msg.sessionId === scope._room.sessionId) return;
            CharacterManager.setCharacterScale(msg.sessionId, msg.x, msg.y, msg.z);
        });

        this._room.onMessage(MMO_MESSAGE_TYPE.PLAYER_ACTION, (msg: IActionMessage) => {
            if (msg.sessionId === scope._room.sessionId) return;
            CharacterManager.setCharacterAction(msg.sessionId, msg.index, msg.loop);
        });

        this._room.onMessage(MMO_MESSAGE_TYPE.PLAYER_VISIBLE, (msg: IBooleanMessage) => {
            if (msg.sessionId === scope._room.sessionId) return;
            CharacterManager.setCharacterVisible(msg.sessionId, msg.value);
        });

    }

}


export { MultiplayerManager };